﻿using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Comdiv.QWeb.Utils;

namespace Comdiv.QWeb.ViewEngine {
	public class QViewContext {
		public string Name { get; set; }
		private string Root { get; set; }
		public string Master { get; set; }
		public IQViewDescriptor ViewDescriptor { get; set; }
		public object ViewData { get; set; }
		public QWebContext Context { get; set; }
		public IQViewFactory Factory { get; set; }
		private IDictionary<string, object> SharedData { get; set; }

		public TextWriter Output { get; set; }
		public bool OutputErrors { get; set; }
		public QViewContext ChildContext { get; private set; }
		public object AdvancedData { get; private set; }

		public T GetShared<T>(string name) {
			if (null == SharedData) return default(T);
			if (!SharedData.ContainsKey(name)) return default(T);
			return SharedData[name].to<T>();
		}

		public void SetShared(string name, object value) {
			if (null == SharedData) SharedData = new Dictionary<string, object>();
			SharedData[name] = value;
		}

		public QViewContext CreateSubviewContext(string name, object advanceddata) {
			var result = MemberwiseClone() as QViewContext;
			Debug.Assert(result != null, "result != null");
			result.Root = Name;
			result.Name = name;
			result.AdvancedData = advanceddata;
			result.Master = null;
			result.NormalizeName();
			return result;
		}

		public QViewContext GetNormalizedContext() {
			if (Master.hasContent()) {
				return GetLayoutedContext();
			}
			if (Root.hasContent() || !Name.StartsWith("/")) {
				var result = MemberwiseClone() as QViewContext;
				Debug.Assert(result != null, "result != null");
				result.NormalizeName();
				return result;
			}

			return this;
		}

		private QViewContext GetLayoutedContext() {
			var mastercontext = MemberwiseClone() as QViewContext;
			var childcontext = MemberwiseClone() as QViewContext;
			Debug.Assert(childcontext != null, "childcontext != null");
			childcontext.Master = null;
			Debug.Assert(mastercontext != null, "mastercontext != null");
			mastercontext.Name = "/layouts/" + Master;
			mastercontext.Root = mastercontext.Name;
			mastercontext.ChildContext = childcontext;
			mastercontext.Master = null;
			return mastercontext;
		}

		private void NormalizeName() {
			if (Name.StartsWith("/")) return;
			var dir = "/";
			if (Root.hasContent()) {
				dir = Root.split(false, true, '/')[0];
			}
			var result = "/" + dir + "/" + Name;
			result = result.Replace("//", "/");
			result = result.Replace("//", "/"); // /// tripple can be created
			Name = result;
		}
	}
}